package org.vin.tempctl.service;

import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetAddress;
import java.net.UnknownHostException;

@Component
public class TemperatureCTL {

    @Value("${Modbus.IP}")
    private String ip;

    @Value("${Modbus.port}")
    private int port;

    @Value("${Modbus.flag}")
    private boolean flag;

    private ModbusMaster master;

    public void say() {
        System.out.println("say--->" + ip);
    }

    @PostConstruct
    public void init() throws UnknownHostException, ModbusIOException {
        System.out.println("------" + ip);
        // 设置主机TCP参数
        TcpParameters tcpParameters = new TcpParameters();
        // 设置TCP的ip地址
        InetAddress adress = InetAddress.getByName(ip);
        // TCP参数设置ip地址
        // tcpParameters.setHost(InetAddress.getLocalHost());
        tcpParameters.setHost(adress);
        // TCP设置长连接
        tcpParameters.setKeepAlive(true);
        // TCP设置端口，这里设置是默认端口502
        //  tcpParameters.setPort(Modbus.TCP_PORT);
        tcpParameters.setPort(port);

        // 创建一个主机
        if (flag) {
            master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
            Modbus.setAutoIncrementTransactionId(true);
            if (!master.isConnected()) {
                master.connect();// 开启连接
            }
        }
    }

    @PreDestroy
    public void preDestroy() {
        if (!flag) {
            return;
        }
        System.out.println("@PreDestroy 执行 销毁 master 实例");
        try {
            if (master != null)
                master.disconnect();
        } catch (ModbusIOException e) {
            e.printStackTrace();
        }
    }

    public int getTemperature() throws Exception {
        if (!flag) {
            return 50;
        }
        int slaveId = 1;//从机地址
        int offset = 2;//寄存器读取开始地址
        int quantity = 1;//读取的寄存器数量
        int[] registerValues;
        registerValues = master.readHoldingRegisters(slaveId, offset, quantity);
        // 控制台输出
        for (int value : registerValues) {
            System.out.println("Address: " + offset++ + ", Value: " + value);
        }
        int readSignedInt32 = (short)registerValues[0];
        return readSignedInt32;//2  温度测量值  RO  0.1
    }

    public int getTemperatureSetting() throws Exception {
        if (!flag) {
            return 50;
        }
        int slaveId = 1;//从机地址
        int offset = 3;//寄存器读取开始地址
        int quantity = 1;//读取的寄存器数量
        int[] registerValues;
        registerValues = master.readHoldingRegisters(slaveId, offset, quantity);
        // 控制台输出
        for (int value : registerValues) {
            System.out.println("Address: " + offset++ + ", Value: " + value);
        }
        int readSignedInt32 = (short)registerValues[0];
        return readSignedInt32;//2  温度测量值  RO  0.1
    }
    public boolean setTemperature(int unit) {
//        if (!flag) {
//            return true;
//        }
        int slaveId = 1;//从机地址
        int offset = 27;//11  温度设定值  RW 0.01 在斜率作用下运行时会发生变化当前设定值
        //int quantity = 1;//读取的寄存器数量
        //boolean ret = false;
        return writeCMDIntoTemp(unit, slaveId, offset);
    }

    public boolean setTemRate(int unit) {
        if (!flag) {
            return true;
        }
        int slaveId = 1;//从机地址
        int offset = 11;//60  温度斜率  RW  0.1
        //int quantity = 1;//读取的寄存器数量
        boolean ret = false;
        return writeCMDIntoTemp(unit, slaveId, offset);
    }

    public boolean setON() {
        if (!flag) {
            return true;
        }
        int slaveId = 1;//从机地址
        int offset = 1;//寄存器开始地址
        int unit = 3;//寄存器
        return writeCMDIntoTemp(unit, slaveId, offset);
    }

    public boolean setOFF() {
        if (!flag) {
            return true;
        }
        int slaveId = 1;//从机地址
        int offset = 1;//寄存器开始地址
        int unit = 2;//寄存器

        return writeCMDIntoTemp(unit, slaveId, offset);
    }

    private boolean writeCMDIntoTemp(int unit, int slaveId, int offset) {
        try {
            if(unit < 0) {
                int unsignedInt16 = unit & 0xFFFF; // 65535
                master.writeSingleRegister(slaveId, offset, unsignedInt16);
            } else {
                master.writeSingleRegister(slaveId, offset, unit);
            }
        } catch (ModbusProtocolException e) {
            e.printStackTrace();
            return false;
        } catch (ModbusNumberException e) {
            e.printStackTrace();
            return false;

        } catch (ModbusIOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }
}
